using System;

namespace Deepcode.Flux.Core.Services.Configuration
{
	/// <summary>
	/// BaseCachedConfigurationFile is an base class that allows 
	/// a property file to be loaded and cached to memory. The cache lasts
	/// for the specified timeout period (in hours), or until the property file
	/// actually changes.
	/// </summary>
	public class BaseCachedConfigurationFile : PropertyFile
	{
		/// <summary>
		/// Override and set the CacheTimeHours to the number of hours between config file loads
		/// </summary>
		protected virtual int CacheTimeHours{ get{ throw new Exception("Inherit the CacheTimeHours GET Accessor"); }}
		/// <summary>
		/// Override and set the CacheKey to a unique key to cache against. Usually using the config filename will be sufficient
		/// </summary>
		protected virtual string CacheKey{ get{ throw new Exception("Inherit the CacheKey GET Accessor"); }}
		/// <summary>
		/// Override and set the full path and filename of the config file.
		/// </summary>
		protected override string FileName{ get{ throw new Exception("Inherit the FileName GET Accessor"); }}
		
		/// <summary>
		/// Load will attempt to load the dictionary from the context cache. If not available,
		/// will then go ahead and load from the physical file on disk.
		/// </summary>
		protected override void LoadPropertyFile()
		{
			// First, check the cache. If it's available, use that
			System.Web.HttpContext c = System.Web.HttpContext.Current;
			if( c != null )
			{
				// Attempt to load the data from the cache
				object cacheList = c.Cache[CacheKey];
				if( cacheList == null )
				{
					// Either this hasn't been cached yet, or it has expired / invalidated - load it
					base.LoadPropertyFile();
					// Now cache it with a dependency
					System.Web.Caching.CacheDependency depend = new System.Web.Caching.CacheDependency(ResolveFileName);
					System.DateTime absExpire = System.DateTime.Now.AddHours(CacheTimeHours);
					c.Cache.Add( CacheKey, 
						this.Properties,
						depend, absExpire, TimeSpan.Zero,
						System.Web.Caching.CacheItemPriority.Normal,
						null );
				}
				else
				{
					// It's a cache hit, use that
					this.Properties = (System.Collections.Hashtable) cacheList;
				}
			}
			else
			{
				// We're not running in web mode!
				throw new Exception("BaseCachedConfigurationFile can only be used when a System.Web.HttpContext.Current is available");
			}
		}
	}
}
